﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.IO;
using System.Threading;
using DevExpress.XtraEditors;
using Microsoft.WindowsAPICodePack.Dialogs;
using SharpSvn;
using SharpSvn.UI;

namespace TDesktop.VersionControl
{
    internal partial class Version : XtraUserControl
    {
        private string vsFile = ConfigurationManager.AppSettings["FileTo"];

        string date = string.Format("{0}-{1}-{2}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
        private string FileTo = null;
        private string log = Application.StartupPath + "\\log.txt";
        private Process cmdUnfile = null;
        private string res = string.Empty;

        public Version()
        {
            InitializeComponent();

            txtFileTo.Text = vsFile;

            FileTo = vsFile + "\\" + date;
        }

        private void btnSetFileTo_Click(object sender, EventArgs e)
        {
            CommonOpenFileDialog fbd = new CommonOpenFileDialog();
            fbd.IsFolderPicker = true;
            fbd.Title = "选择版本库文件夹";
            if (fbd.ShowDialog() != CommonFileDialogResult.Ok)
            {
                return;
            }

            txtFileTo.Text = fbd.FileName;
            //txtFileTo.Text = fbd.SelectedPath;
            vsFile = txtFileTo.Text;
            FileTo = vsFile + "\\" + date;

            //写配置文件
            Configuration cfa = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            cfa.AppSettings.Settings["FileTo"].Value = txtFileTo.Text;
            cfa.Save();
        }

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openfile = new OpenFileDialog();
            openfile.Multiselect = false;
            openfile.Filter = "*.rar,*.zip,*.7z|*.rar;*.zip;*.7z";
            if (openfile.ShowDialog() != DialogResult.OK || openfile.FileName == null)
                return;

            txtPath.Text = openfile.FileName;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (txtPath.Text == string.Empty)
            {
                MessageBox.Show(this, "请选择压缩包");
                return;
            }

            string RARname = Path.GetFileNameWithoutExtension(txtPath.Text);
            string filePath = FileTo + "\\" + RARname + "_版本说明.txt";
            if (File.Exists(filePath))
            {
                if (MessageBox.Show(this, "文件好像已经存在，是否覆盖？", "问题", MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    DialogResult.No)
                {
                    return;
                }
            }

            if (txtLog.Text == string.Empty)
            {
                if (MessageBox.Show(this, "日志为空，是否继续？（不推荐为空）", "问题", MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
                    DialogResult.No)
                {
                    return;
                }
            }

            Control.CheckForIllegalCrossThreadCalls = false;

            SetReadOnly();

            Thread newThread = new Thread(UNRAR);
            newThread.Start();
        }

        /// <summary>
        /// 线程解压缩
        /// </summary>
        private void UNRAR()
        {
            ReadFile(txtPath.Text);

            UNfile(txtPath.Text, FileTo);

            MakeLog(txtLog.Text);

            SetReadOnly();

            if (MessageBox.Show(this, "是否直接上传至SVN服务器？", "疑问", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                SVNCommit();
            }

            System.Diagnostics.Process.Start("explorer.exe", FileTo);
        }

        private void SetReadOnly()
        {
            txtLog.ReadOnly = !txtLog.ReadOnly;
            btnOpenFile.Enabled = !btnOpenFile.Enabled;
            btnSetFileTo.Enabled = !btnSetFileTo.Enabled;
            btnStart.Enabled = !btnStart.Enabled;
        }

        #region 解压方法

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="log"></param>
        /// <returns></returns>
        private int MakeLog(string log)
        {
            int rv = 0;

            string RARname = Path.GetFileNameWithoutExtension(txtPath.Text);
            string filePath = FileTo + "\\" + RARname + "_版本说明.txt";

            try
            {
                System.IO.File.WriteAllText(filePath, log, Encoding.Default);
            }
            catch (Exception e)
            {
                MessageBox.Show(this, e.Message);
                return -1;
            }

            progressBar1.Position = progressBar1.Properties.Maximum;
            labLog.Text = "日志添加成功";
            return rv;
        }

        /// <summary>
        /// 查看压缩包内文件
        /// </summary>
        /// <param name="fileFrom"></param>
        /// <returns></returns>
        private int ReadFile(string fileFrom)
        {
            int rv = 0;

            if (!Directory.Exists(FileTo))
            {
                Directory.CreateDirectory(FileTo);
            }
            progressbarRes(0);
            labLog.Text = "读取文件：" + Path.GetFileName(fileFrom);
            try
            {
                using (Process process1 = new Process())
                {
                    //string ServerDir = Application.StartupPath + "/haoya/HaoZipC.exe";
                    //string ServerDir = Application.StartupPath + "\\cmd.exe";
                    string ServerDir = "C:\\WINDOWS\\system32\\cmd.exe";
                    process1.StartInfo.UseShellExecute = false;
                    process1.StartInfo.RedirectStandardInput = true;
                    process1.StartInfo.RedirectStandardOutput = true;
                    process1.StartInfo.RedirectStandardError = true;
                    process1.StartInfo.CreateNoWindow = true;
                    process1.StartInfo.FileName = ServerDir;
                    //process1.StartInfo.Arguments = Application.StartupPath + "\\haoya\\HaoZipC.exe" + " x " + fileFrom + " -o" + fileTo;
                    process1.Start();
                    process1.StandardInput.WriteLine(Application.StartupPath + "\\haoya\\HaoZipC.exe" + " l " + fileFrom);
                    process1.StandardInput.WriteLine("exit");
                    res = process1.StandardOutput.ReadToEnd();
                    //process1.StandardInput.WriteLine(Application.StartupPath + "\\haoya\\HaoZipC.exe" + " x " + fileFrom + " -o" + fileTo);
                    process1.WaitForExit();
                    process1.Close();
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(this, e.Message);
                labLog.Text = "解压失败";
                return -1;
            }

            System.IO.File.WriteAllLines(log, res.Split('\n'), Encoding.Default);

            progressbarRes(GetAllFileCount(log) + 10);

            labLog.Text = "读取成功，开始解压文件";
            return rv;
        }

        /// <summary>
        /// 解压缩文档
        /// </summary>
        /// <returns></returns>
        private int UNfile(string fileFrom, string fileTo)
        {
            int rv = 0;

            res = string.Empty;
            Control.CheckForIllegalCrossThreadCalls = false; //取消错误调用提示

            using (cmdUnfile = new Process())
            {
                cmdUnfile.StartInfo.FileName = "cmd.exe";
                cmdUnfile.StartInfo.UseShellExecute = false;
                cmdUnfile.StartInfo.RedirectStandardInput = true;
                cmdUnfile.StartInfo.RedirectStandardOutput = true;
                cmdUnfile.StartInfo.CreateNoWindow = true;
                cmdUnfile.EnableRaisingEvents = true;
                cmdUnfile.OutputDataReceived += (sender, outLine) =>
                {
                    if (!string.IsNullOrEmpty(outLine.Data))
                    {
                        labLog.Text = outLine.Data;
                        progressBar1.PerformStep();
                        StringBuilder sb = new StringBuilder(res);
                        res = sb.AppendLine(outLine.Data).ToString();
                    }
                };
                cmdUnfile.Start();

                cmdUnfile.StandardInput.WriteLine(Application.StartupPath + "\\haoya\\HaoZipC.exe" + " x " + fileFrom +
                                                  " -o" + fileTo + " -y");

                cmdUnfile.BeginOutputReadLine();

                cmdUnfile.StandardInput.WriteLine("exit");


                cmdUnfile.WaitForExit();
                cmdUnfile.Close();
            }

            System.IO.File.WriteAllLines(log, res.Split('\n'), Encoding.Default);
            return rv;
        }

        /// <summary>
        /// 获得压缩包内的文件数量
        /// </summary>
        /// <param name="output"></param>
        /// <returns></returns>
        private int GetAllFileCount(string output)
        {
            int res = 0;
            string[] outStrings = System.IO.File.ReadAllLines(output, Encoding.Default);
            string info = outStrings[outStrings.Length - 7];

            string[] strings = info.Split(' ');
            for (int i = 0; i < strings.Length; i++)
            {
                if (strings[i] == "个文件，")
                {
                    res = Int32.Parse(strings[i - 1]);
                    break;
                }
            }
            return res;
        }

        private void progressbarRes(int max)
        {
            progressBar1.Properties.Minimum = 0;
            progressBar1.Properties.Maximum = (max == 0 ? 100 : max + 30);
            progressBar1.Position = 0;
            progressBar1.Properties.Step = 1;
        }


        #endregion

        #region 拖拽

        /// <summary>
        /// 拖拽进入页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Move;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        /// <summary>
        /// 拖拽完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_DragDrop(object sender, DragEventArgs e)
        {
            Array aryFile = ((Array)e.Data.GetData(DataFormats.FileDrop));
            string path = aryFile.GetValue(0).ToString();
            string ext = Path.GetExtension(path).ToLower().Trim();
            if (ext != ".rar" && ext != ".zip" && ext != ".7z")
            {
                MessageBox.Show(this, "放置文件类型不正确", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            txtPath.Text = path;
        }

        #endregion

        #region SVN

        private void SVNCommit()
        {
            using (SvnClient client = new SvnClient())
            {
                bool isalready = true;
                labLog.Text = "正在整理中，请等候";

                progressbarRes(0);

                SvnUIBindArgs uiBindArgs = new SvnUIBindArgs();
                SvnUI.Bind(client, uiBindArgs);

                string strLocalUri = FileTo; //本地副本地址，先增加带日期的文件夹

                #region 注释

                //SvnInfoEventArgs info;  //Info参数    

                //client.GetInfo(new Uri(strRepoUri), out info); //调用GetInfo()方法   

                //Console.WriteLine(info.Revision.ToString()); //输出版本  
                ////Console.WriteLine(info.ChangeList.ToString());
                //Console.WriteLine(info.Depth.ToString());


                //SvnImportArgs importArgs = new SvnImportArgs(); //Import参数  

                //importArgs.LogMessage = "Improt Test"; //Import时的日志信息   


                #endregion

                try
                {
                    labLog.Text = "正在添加  " + strLocalUri;
                    client.Add(strLocalUri);


                    //client.Import(strLocalUri + "test.txt", new Uri(strRepoUri), importArgs); //执行Svn 的Import命令 
                    SvnCommitArgs commit = new SvnCommitArgs();
                    commit.LogMessage = txtLog.Text;
                    labLog.Text = "正在上传...";
                    timer();
                    client.Commit(strLocalUri, commit);

                }
                catch (Exception e)
                {
                    if (!e.Message.Contains("is already under version control"))
                    {
                        isalready = false;
                        if (e.Message.Contains("is not a working copy"))
                        {
                            MessageBox.Show("'" + vsFile + "'" + "  不在版本控制内！上传失败！");
                            return;
                        }

                        MessageBox.Show(this, e.Message);
                        return;
                    }

                    List<string> folders = new List<string>();

                    string[] outStrings = File.ReadAllLines(log, Encoding.Default);

                    labLog.Text = "正在查找文件夹";
                    progressBar1.PerformStep();

                    for (int i = 4; i < outStrings.Length - 8; i++)
                    {
                        if (!outStrings[i].Contains("正在解压")) continue;
                        string folder = outStrings[i].Replace("正在解压", "").Trim().Split('\\')[0];
                        if (!folders.Contains(folder))
                        {
                            folders.Add(folder);
                            labLog.Text = "正在查找文件夹  " + folder;
                        }
                        progressBar1.Position += 25 / (outStrings.Length - 12);
                    }
                    //开始重新升级
                    try
                    {
                        for (int i = 0; i < folders.Count; i++)
                        {
                            labLog.Text = "正在添加  " + strLocalUri + "\\" + folders[i];
                            client.Add(strLocalUri + "\\" + folders[i]);
                            progressBar1.Position += 25 / folders.Count;
                        }

                        client.Add(strLocalUri + "\\" + Path.GetFileNameWithoutExtension(txtPath.Text) + "_版本说明.txt");

                        SvnCommitArgs commit = new SvnCommitArgs();
                        commit.LogMessage = txtLog.Text;
                        labLog.Text = "正在上传...";
                        timer();
                        client.Commit(strLocalUri, commit);

                    }
                    catch (Exception ext)
                    {
                        isalready = false;
                        MessageBox.Show(this, ext.Message);
                        return;
                    }
                }
                finally
                {
                    progressBar1.Position = progressBar1.Properties.Maximum;
                    if (isalready)
                    {
                        MessageBox.Show(this, "上传成功！");
                        labLog.Text = "上传成功";
                    }
                    else
                    {
                        labLog.Text = "上传失败";
                    }
                }
            }
        }

        #endregion

        private void timer()
        {
            System.Timers.Timer timer = new System.Timers.Timer(1200);
            timer.Elapsed += (sender, e) =>
            {
                if (progressBar1.Position >= 90)
                {
                    timer.Stop();
                    timer.Dispose();
                }
                progressBar1.PerformStep();
            };
            timer.Enabled = true;
            timer.AutoReset = true;
            timer.Start();
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
